home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / system / source / math.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-12-15  |  3.5 KB  |  127 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #include "stdafx.h"
  27. #include <math.h>
  28. #include <vd2/system/math.h>
  29. #include <vd2/system/int128.h>
  30.  
  31. int VDRoundToInt(double x) {
  32.     return (int)floor(x + 0.5);
  33. }
  34.  
  35. long VDRoundToLong(double x) {
  36.     return (long)floor(x + 0.5);
  37. }
  38.  
  39. sint32 VDRoundToInt32(double x) {
  40.     return (sint32)floor(x + 0.5);
  41. }
  42.  
  43. sint64 VDRoundToInt64(double x) {
  44.     return (sint64)floor(x + 0.5);
  45. }
  46.  
  47. #ifdef _M_IX86
  48.     sint64 __declspec(naked) __stdcall VDFractionScale64(uint64 a, uint32 b, uint32 c, uint32& remainder) {
  49.         __asm {
  50.             push    edi
  51.             push    ebx
  52.             mov        edi, [esp+12+8]            ;edi = b
  53.             mov        eax, [esp+4+8]            ;eax = a[lo]
  54.             mul        edi                        ;edx:eax = a[lo]*b
  55.             mov        ecx, eax                ;ecx = (a*b)[lo]
  56.             mov        eax, [esp+8+8]            ;eax = a[hi]
  57.             mov        ebx, edx                ;ebx = (a*b)[mid]
  58.             mul        edi                        ;edx:eax = a[hi]*b
  59.             add        eax, ebx
  60.             mov        ebx, [esp+16+8]            ;ebx = c
  61.             adc        edx, 0
  62.             div        ebx                        ;eax = (a*b)/c [hi], edx = (a[hi]*b)%c
  63.             mov        edi, eax                ;edi = (a[hi]*b)/c
  64.             mov        eax, ecx                ;eax = (a*b)[lo]
  65.             mov        ecx, [esp+20+8]
  66.             div        ebx                        ;eax = (a*b)/c [lo], edx = (a*b)%c
  67.             mov        [ecx], edx
  68.             mov        edx, edi
  69.             pop        ebx
  70.             pop        edi
  71.             ret        20
  72.         }
  73.     }
  74.  
  75.     uint64 __declspec(naked) __stdcall VDUMulDiv64x32(uint64 a, uint32 b, uint32 c) {
  76.         __asm {
  77.             mov        eax, [esp+4]            ;eax = a0
  78.             mul        dword ptr [esp+12]        ;edx:eax = a0*b
  79.             mov        dword ptr [esp+4], eax    ;tmp = a0*b[0:31]
  80.             mov        ecx, edx                ;ecx = a0*b[32:63]
  81.             mov        eax, [esp+8]            ;eax = a1
  82.             mul        dword ptr [esp+12]        ;edx:eax = a1*b
  83.             add        eax, ecx                ;edx:eax += a0*b[32:95]
  84.             adc        edx, 0                    ;(cont.)
  85.             cmp        edx, [esp+16]            ;test if a*b[64:95] >= c; equiv to a*b >= (c<<64)
  86.             jae        invalid                    ;abort if so (overflow)
  87.             div        dword ptr [esp+16]        ;edx,eax = ((a*b)[32:95]/c, (a*b)[32:95]%c)
  88.             mov        ecx, eax
  89.             mov        eax, [esp+4]
  90.             div        dword ptr [esp+16]
  91.             mov        edx, ecx
  92.             ret        16
  93. invalid:
  94.             mov        eax, -1                    ;return FFFFFFFF'FFFFFFFF
  95.             mov        edx, -1
  96.             ret        16
  97.         }
  98.     }
  99. #endif
  100.  
  101. sint64 VDMulDiv64(sint64 a, sint64 b, sint64 c) {
  102.     bool flip = false;
  103.  
  104.     if (a < 0) {
  105.         a = -a;
  106.         flip = true;
  107.     }
  108.  
  109.     if (b < 0) {
  110.         b = -b;
  111.         flip = !flip;
  112.     }
  113.  
  114.     if (c < 0) {
  115.         c = -c;
  116.         flip = !flip;
  117.     }
  118.  
  119.     uint64 rem;
  120.     uint64 v = VDUDiv128x64To64(VDUMul64x64To128((uint64)a, (uint64)b), (uint64)c, rem);
  121.  
  122.     if ((rem+rem) >= (uint64)c)
  123.         ++v;
  124.  
  125.     return flip ? -(sint64)v : (sint64)v;
  126. }
  127.